<?php
declare(strict_types=1);

namespace App\Services\Business;

use App\Exceptions\BasicException;
use App\Models\MainDB\Business;
use App\Models\MainDB\BusinessConfig;
use App\Models\MainDB\RechargeWhitelist;
use App\Models\MainDB\RechargeWhitelistNew;
use Illuminate\Support\Facades\DB;

class BusinessConfigService
{
    public const SWITCH_LOGIC_TYPES_RECHARGE = 'recharge';
    public const SWITCH_LOGIC_TYPES_WHITELIST = 'whitelist';
    public const PRIORITY_VALUE = 99;

    public const PAY_TYPE_ALI = 'ali';
    public const PAY_TYPE_WECHAT = 'wechat';
    public const PAY_TYPE_WECHAT_H5 = 'wechat_h5';

    public const PAY_CHANNEL_OFFICIAL = 'official';//原生
    public const PAY_CHANNEL_FWS = 'fws';//原生 服务商
    public const PAY_CHANNEL_MIHUA = 'miHua'; //米花
    public const PAY_CHANNEL_SAND = 'sand'; //杉德
    public const PAY_CHANNEL_OFFICIAL_H5 = 'official_h5'; // 原生 h5
    public const PAY_CHANNEL_WBAO = 'wbao'; //微宝
    public const PAY_CHANNEL_QUJIN = 'QJ'; //qujin 第三方支付
    public const PAY_CHANNEL_ADA = 'ada'; //adapay
    public const PAY_CHANNEL_YL = 'yl'; //adapay
    public const PAY_CHANNEL_DATA = 'PAY_CHANNEL_DATA'; //adapay
    public const PAY_CHANNEL_XCX = 'xcx'; // 原生 h5

    public function getOne(int $userId, string $money, string $payType, $payChannel = ''): ?BusinessConfig
    {
//        if ($payType === self::PAY_TYPE_ALI) {
//            $money *= 100;
//        }
        $businessConfigModel = new BusinessConfig();
        if($payType == 'wechat'){
            if (!app('redis')->exists(self::PAY_CHANNEL_DATA)) {
                // 设置 对标 商户 id 和 1 = > id
                $business_arr = $businessConfigModel->query()->where('pay_type', $payType)->where('is_status', 1)->get()->pluck('id')->toArray();
                app('redis')->set(self::PAY_CHANNEL_DATA, json_encode($business_arr));
            }
        }
        $qb = $businessConfigModel::query()
            ->where('status', 1)
            ->where('is_exclusive', 0)
            ->where('pay_type', $payType);
        if ($payChannel) {
            $qb->where('pay_channel', $payChannel);
        }
        $configList = $qb->get();

//        $userIdArr = RechargeWhitelist::query()->get()->pluck('user_id')->toArray();
        $userIdArr = RechargeWhitelistNew::query()->get()->pluck('user_id')->toArray();

        $configList->transform(function ($item) use ($userId, $money, $userIdArr) {

            $item->available = false;
            $item->priority = 0;

            $switchLogicTypes = explode(',', $item->switch_logic_type);

            if (in_array(self::SWITCH_LOGIC_TYPES_WHITELIST, $switchLogicTypes, true)) {

                if (in_array($userId, $userIdArr, true)) {
                    $item->priority = self::PRIORITY_VALUE;
                }

            }

            if (in_array(self::SWITCH_LOGIC_TYPES_RECHARGE, $switchLogicTypes, true)) {
                if ($money <= $item->max_money && $money >= $item->min_money) {
                    $item->available = true;
                }
            }

            return $item;
        });

        //优先选择白名单配置商户
        $configInfo = $configList->where('priority', self::PRIORITY_VALUE)
            ->shuffle()
            ->first();

        if (empty($configInfo)) {
            $configInfo = $configList->where('available', true)
                ->shuffle()
                ->first();
        }

        if ($configInfo) {
            $configInfo->params = $configInfo->param ? json_decode($configInfo->param, true) : null;
        }
        return $configInfo;
    }

    /**
     * @param int $userId
     * @param string $money
     * @param string $payType
     * @param $id
     * @param string $payChannel
     * @return BusinessConfig|null
     * @throws \Exception
     */
    public function getNEWOne(int $userId, string $money, string $payType, $id, $payChannel = ''): ?BusinessConfig
    {
        // 修改订单状态

        $businessConfigModel = new BusinessConfig();
        DB::beginTransaction();
        try {
            $businessConfigModel::query()
                ->where('id', $id)->update([
                    'status' => 1
                ]);
            $businessConfigModel::query()
                ->where('pay_type', $payType)
                ->where('id', '<>', $id)->update([
                    'status' => 0
                ]);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw new BasicException(-1, '商户切换失败');
        }
        $qb = $businessConfigModel::query()
            ->where('id', $id)
            ->where('is_exclusive', 0)
            ->where('pay_type', $payType);
        if ($payChannel) {
            $qb->where('pay_channel', $payChannel);
        }
        $configList = $qb->get();
        $userIdArr = RechargeWhitelist::query()->get()->pluck('user_id')->toArray();

        $configList->transform(function ($item) use ($userId, $money, $userIdArr) {

            $item->available = false;
            $item->priority = 0;

            $switchLogicTypes = explode(',', $item->switch_logic_type);

            if (in_array(self::SWITCH_LOGIC_TYPES_WHITELIST, $switchLogicTypes, true)) {

                if (in_array($userId, $userIdArr, true)) {
                    $item->priority = self::PRIORITY_VALUE;
                }

            }

            if (in_array(self::SWITCH_LOGIC_TYPES_RECHARGE, $switchLogicTypes, true)) {
                if ($money <= $item->max_money && $money >= $item->min_money) {
                    $item->available = true;
                }
            }

            return $item;
        });

        //优先选择白名单配置商户
        $configInfo = $configList->where('priority', self::PRIORITY_VALUE)
            ->shuffle()
            ->first();

        if (empty($configInfo)) {
            $configInfo = $configList->where('available', true)
                ->shuffle()
                ->first();
        }

        if ($configInfo) {
            $configInfo->params = $configInfo->param ? json_decode($configInfo->param, true) : null;
        }
        return $configInfo;
    }

    /**
     * @param int $id
     * @return BusinessConfig|null
     */
    public function getById(int $id): ?BusinessConfig
    {
        $businessConfigModel = new BusinessConfig();
        $configInfo = $businessConfigModel::query()->find($id);
        if ($configInfo) {
            $configInfo->params = $configInfo->param ? json_decode($configInfo->param, true) : null;
        }
        return $configInfo;
    }


    public function getUserRechargeType(string $payType, string $payChannel): int
    {
        // `type` int(11) DEFAULT '0' COMMENT
        // '1.支付宝  2.微信 3.苹果内购
        // 4.h5支付宝 5.h5微信', 6. 杉徳支付宝h5,
        // 7.杉徳微信h5, 8.杉徳支付宝App, 9.杉徳微信App,
        // 10.ada支付宝，11.ada微信，12.ada支付宝h5
        // 13.yl支付宝，14.yl微信，15.ylh5
        // 16.weibao支付宝，17.weibao微信，18.weibaoh5  19 QJ  20 xcx  21 ail_xcx
        $map = [
            self::PAY_TYPE_ALI => [
                self::PAY_CHANNEL_OFFICIAL => 1,
                self::PAY_CHANNEL_SAND => 8,
                self::PAY_CHANNEL_ADA => 10,
                self::PAY_CHANNEL_YL => 13,
                self::PAY_CHANNEL_WBAO => 16,
                self::PAY_CHANNEL_QUJIN => 19,
                self::PAY_CHANNEL_XCX => 21,
            ],
            self::PAY_TYPE_WECHAT => [
                self::PAY_CHANNEL_OFFICIAL => 2,
                self::PAY_CHANNEL_SAND => 9,
                self::PAY_CHANNEL_ADA => 11,
                self::PAY_CHANNEL_YL => 14,
                self::PAY_CHANNEL_WBAO => 17,
                self::PAY_CHANNEL_OFFICIAL_H5 => 5,
                self::PAY_CHANNEL_XCX => 20,
            ],
            self::PAY_TYPE_WECHAT_H5 => [
                self::PAY_CHANNEL_OFFICIAL => 5,
                self::PAY_CHANNEL_SAND => 7,
                self::PAY_CHANNEL_ADA => 12,
                self::PAY_CHANNEL_YL => 15,
                self::PAY_CHANNEL_WBAO => 18,
            ],

        ];
        return $map[$payType][$payChannel];
    }

    public function getExclusiveOfficialChannels($peyType = '')
    {
        $model = BusinessConfig::query();
        $model->where('pay_channel', self::PAY_CHANNEL_OFFICIAL);
        if (!empty($peyType)) {
            $model->where('pay_type', $peyType);
        }
        $model->where('is_exclusive', 1);
        return $model->get();
    }


    public function getAliOrAdaChannels()
    {
        $model = BusinessConfig::query();
        $model->whereIn('pay_channel', [self::PAY_CHANNEL_OFFICIAL, self::PAY_CHANNEL_ADA]);
        $model->where('is_exclusive', 1);
        $model->where('pay_type', self::PAY_TYPE_ALI);
        return $model->get();
    }

}
